﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VehicleScale.Models;
using VehicleScale.EntityMappers;
using System.Diagnostics;

namespace VehicleScale.DataAccess
{
    public class ProductDataAccess : BaseDataAccess, IProductDataAccess
    {

        #region Properties

        private ProductModel _searchObject;
        /// <summary>
        /// Search Object Property
        /// </summary>
        public ProductModel SearchObject
        {
            get
            {
                return _searchObject;
            }
            set
            {
                if (_searchObject != value)
                {
                    _searchObject = value;
                }
            }
        }
        #endregion

        #region Methods
        public IList<ProductModel> Searcher()
        {
            IList<ProductModel> collection = null;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    IQueryable<Product> query = dataContext.Products;
                    if (!String.IsNullOrEmpty(_searchObject.ProductID))
                    {
                        query = query.Where(e => e.ProductID.Contains(_searchObject.ProductID));
                        //hasConditions = true;
                    }
                    if (!String.IsNullOrEmpty(_searchObject.ProductName))
                    {
                        query = query.Where(e => e.ProductName.Contains(_searchObject.ProductName));
                        //hasConditions = true;
                    }
                    if (!String.IsNullOrEmpty(_searchObject.CategoryID))
                    {
                        query = query.Where(e => e.CategoryID == _searchObject.CategoryID);
                        //hasConditions = true;
                    }

                    collection = new List<ProductModel>();
                    foreach (var item in query)
                    {
                        collection.Add(ProductMapper.ToModel(item));
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return collection;
        }

        public IList<ProductModel> GetAll()
        {
            IList<ProductModel> collection = null;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    IQueryable<Product> query = dataContext.Products;

                    collection = new List<ProductModel>();
                    foreach (var item in query)
                    {
                        collection.Add(ProductMapper.ToModel(item));
                    }

                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return collection;
        }

        public ProductModel Get()
        {
            ProductModel item = null;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Product query = dataContext.Products.FirstOrDefault();

                    if (query != null) item = ProductMapper.ToModel(query);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }

            return item;
        }

        public ProductModel GetLast()
        {
            ProductModel item = null;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Product query = dataContext.Products.LastOrDefault();

                    if (query != null) item = ProductMapper.ToModel(query);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }

            return item;
        }

        /// <summary>
        /// Generate Auto ID Method
        /// </summary>
        /// <param name="dataContext"></param>
        /// <returns></returns>
        private string GenerateAutoID(DataClassesDataContext dataContext)
        {
            string id = String.Empty;

            try {
            int length = 20; // length default
            string prefix = String.Empty;
            string startNumber = "1";
            string defaultID = String.Empty;

            // Create Default Key
            Config config = dataContext.Configs.FirstOrDefault();
            if (config != null)
            {
                prefix = config.ProductPrefix;
                length = config.ProductCodeLength;
            }
            defaultID = prefix + startNumber.PadLeft(length, '0');

            // Create Automation Key
            var query = dataContext.Products.Where(e =>
                e.ProductID.StartsWith(prefix));
            if (query != null)
                id = query.Max(e => e.ProductID);

            if (String.IsNullOrEmpty(id))
                id = defaultID;
            else
            {
                id = id.Remove(0, prefix.Length);
                int numberID;
                string suffix;
                if (Int32.TryParse(id, out numberID))
                {
                    numberID++;
                    suffix = numberID.ToString().PadLeft(length, '0');
                    id = prefix + suffix;
                }
                else
                {
                    id = defaultID;
                }
            }
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            // End Create Automation Key
            return id;
        }

        public bool Add(ProductModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    if (String.IsNullOrEmpty(item.ProductID))
                    {
                        item.ProductID = GenerateAutoID(dataContext);
                    }

                    Product entity = new Product();
                    ProductMapper.ToEntity(entity, item);
                    dataContext.Products.InsertOnSubmit(entity);
                    dataContext.SubmitChanges();
                    result = true;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        }

        public bool Add(IList<ProductModel> collection)
        {
            throw new NotImplementedException();
        }

        public bool Edit(ProductModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Product entity = dataContext.Products.Where(e => e.ProductID == item.ProductID).SingleOrDefault();
                    if (entity != null)
                    {
                        ProductMapper.ToEntity(entity, item);
                        dataContext.SubmitChanges();
                        result = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        }

        public bool Edit(IList<ProductModel> collection)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Delete Method
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Delete(ProductModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Product entity = dataContext.Products.Where(e => e.ProductID == item.ProductID).SingleOrDefault();
                    dataContext.Products.DeleteOnSubmit(entity);
                    dataContext.SubmitChanges();
                    result = true;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        }

        public bool Delete(IList<ProductModel> collection)
        {
            throw new NotImplementedException();
        }

        #endregion

    }
}
